home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-05-24 | 14.1 KB | 434 lines | [TEXT/MPS ] |
- ;-----------------------------------------------------------------
-
- ;General directives
-
- BLANKS ON
- STRING ASIS
-
-
- ;=====================================================================
- ; Local Vars, definitions, etc....
- ;=====================================================================
-
- ; This is device storage which is stored in the dCtlStorage field of the DCE.
-
- DCEPtr EQU 0 ; pointer to our DCE
- saveMode EQU DCEPtr+4 ; the current mode setting
- savePage EQU saveMode+2 ; the current page setting
- saveBaseAddr EQU savePage+2 ; the current base address
- saveSQElPtr EQU saveBaseAddr+4 ; the SQ element pointer (for _SIntRemove).
- GammaPtr EQU saveSQElPtr+4 ; the pointer to the Gamma correction table
- GFlags EQU GammaPtr+4 ; flags word
- VRAM256K EQU GFlags+2 ; boolean - TRUE if 256K vidRAM, FALSE if 512K
- dCtlSize EQU VRAM256K+2 ; size of dCtlStorage
-
- ; Flags within GFlags word
-
- GrayFlag EQU 15 ; luminance mapped if GFlags(GrayFlag) = 1
- TFB1K EQU 0
-
- ;=====================================================================
- ; Video Driver Header
- ;=====================================================================
-
- VidDrvr DC.W $4C00 ; ctl,status,needsLock
- DC.W 0,0,0 ; not an ornament
-
- ; Entry point offset table
-
- DC.W VideoOpen-VidDrvr ; open routine
- DC.W VidDrvr-VidDrvr ; no prime
- DC.W VideoCtl-VidDrvr ; control
- DC.W VideoStatus-VidDrvr ; status
- DC.W VideoClose-VidDrvr ; close
-
-
- STRING Pascal
- VideoTitle DC.B '.Display_Video_Apple_TFB' ;
- STRING ASIS
- ALIGN 2 ; make sure we're aligned
- DC.W 0 ; version-0
-
- ;
- **********************************************************************
- *
- * VideoOpen allocates private storage for the device in the DCE and locks
- * it down for perpituity. Also, install the interrupt handler and enable
- * the interrupts. <22Sep86>
- * It also sets the default gamma table included in the driver
- *
- * Entry: A0 = param block pointer
- * A1 = DCE pointer
- *
- * Locals: A2 = Saved param block pointer
- * A3 = Saved DCE pointer
- * A4 = Saved interrupt handler ptr.
- *
- **********************************************************************
-
- ; Save registers
- VideoOpen MOVE.L A0,A2 ;A2 <- param block pointer
- MOVE.L A1,A3 ;A3 <- DCE pointer
-
- ; Allocate private storage.
- MOVEQ #dCtlSize,D0 ; get size of parameters
- _ResrvMem ,SYS ; make room as low as possible
- MOVEQ #dCtlSize,D0 ; get size of parameters
- _NewHandle ,SYS,CLEAR ; get some memory for private storage
- BNE OpError ; => return an error in open
- MOVE.L A0,dCtlStorage(A3) ; save returned handle in DCE
- _HLock ; and lock it down
-
- ; Get and install the interrupt handler.
- LEA BeginIH,A4 ;Save Pointer to interrupt handler.
- MOVEQ #sqHDSize,D0 ;allocate a slot queue element
- _NewPtr ,SYS,CLEAR ;get it from system heap cleared
- BNE OpError
- MOVE.W #SIQType,SQType(A0) ;setup queue ID
- MOVE.L A4,SQAddr(A0) ;setup int routine address
- MOVE.L dctlDevBase(A3),SQParm(A0) ;save slot base addr as A3 parm
- CLR.L D0
- MOVE.B dctlSlot(A3),D0 ;setup slot #
- _SIntInstall ;and do install
- BNE.S OpError
-
- ; Save SQElPtr for removal.
- MOVE.L dCtlStorage(A3),A1 ;Get pointer to private storage.
- MOVE.L (A1),A1 ;
- MOVE.L A0,saveSQElPtr(A1) ;Save the SQ element pointer.
-
- ; Enable interrupts..
- ADD.L #ClrVInt,A0 ;bump to interrupt reg
- CLR.B (A0) ;clear it.
-
- MOVEQ #0,D0 ;no error
- BRA.S EndOpen
-
- ; Error.
- OpError MOVE.L #OpenErr,D0 ; say can't open driver.
-
-
- EndOpen RTS ;return
-
- ;
- ;-------------------------------------------------------------
- ; The Interrupt handler for TFB board
- ;-------------------------------------------------------------
- ; The interrupt Handler
- ; On entry A1 contains the slot base address
- ; D0-D3/A0-A3 have been preserved.
- BeginIH MOVE.L A1,A0 ; get screen base
- MOVE.L A1,D0 ; and save for later
- ADD.L #ClrVInt,A0 ; get offset to register
- CLR.B (A0) ; clear interrupt from card
-
- ; D0 = $Fssxxxxx
- ROL.L #8,D0 ; D0 <- $sxxxxxFs Convert the address into
- AND #$0F,D0 ; D0 <- $sxxx000s the slot number.
-
- MOVE.L JVBLTask,A0 ; call the VBL task manager
- JSR (A0) ; with slot # in D0
-
- MOVEQ #1,D0 ; signal that int was serviced
- RTS ; and return to caller
-
-
- ;
- **********************************************************************
- *
- * VideoClose releases the device's private storage.
- *
- *
- * Entry: A0 = param block pointer
- * A1 = DCE pointer
- *
- * Locals: A2 = Saved param block pointer
- * A3 = Saved DCE pointer
- * A4 = Temporary.
- *
- **********************************************************************
-
- VideoClose
- MOVE.L A0,A2 ;A2 <- param block pointer
- MOVE.L A1,A3 ;A3 <- DCE pointer
-
- MOVE.L dCtlDevBase(A3),A4 ;A4 <- base address of device.
- ADD.L #DisableVInt,A4 ;Adjust the base
- CLR.B (A4) ;Disable interrupt from card
-
- MOVE.L dCtlStorage(A3),A0 ;Get pointer to private storage
- MOVE.L (A0),A0 ;
- MOVE.L saveSQElPtr(A0),A0 ;Get the SQ element pointer.
- _SIntRemove ;Remove the interrupt handler.
-
- MOVE.L dCtlStorage(A3),A0 ;Get pointer to private storage
- MOVE.L (A0),A0 ;
- MOVE.L GammaPtr(A0),A0 ;get pointer to gamma table
- _DisposPtr ;and dispose it
-
- MOVE.L dCtlStorage(A3),A0 ;Dispose of the private storage.
- _DisposHandle ;
-
-
- MOVEQ #0,D0 ;get error into D0
- RTS ;return to caller
-
-
- ;
- **********************************************************************
- *
- * Video Driver Control Call Handler. Right now there are six calls:
- *
- * (0) Reset (VAR mode, page: INTEGER; VAR BaseAddr: Ptr);
- * (1) KillIO
- * (2) SetMode(mode, page: INTEGER; VAR BaseAddr: Ptr);
- *
- * Entry: A0 = param block pointer
- * A1 = DCE pointer
- * Uses: A2 = cs parameters (ie. A2 <- csParam(A0)) (must be preserved)
- * A3 = scratch (doesn't need to be preserved)
- * A4 = scratch (must be preserved)
- * D0-D3 = scratch (don't need to be preserved)
- *
- * Exit: D0 = error code
- *
- **********************************************************************
-
- ; Decode the call
- VideoCtl MOVEM.L A0/A4/D4,-(SP) ; save work registers (A0 is saved because it is used by ExitDrvr).
-
- MOVE.W csCode(A0),D0 ; get the opCode
- MOVE.L csParam(A0),A2 ; A2 <- Ptr to control parameters
-
- CMP.W #2,D0 ;IF csCode NOT IN [0..6] THEN
- BHI.S CtlBad ; Error, csCode out of bounds.
- LSL.W #1,D0 ;Adjust csCode to be an index into the table.
- MOVE.W CtlJumpTbl(PC,D0.W),D0 ;Get the relative offset to the routine.
- JMP CtlJumpTbl(PC,D0.W) ;GOTO the proper routine.
-
- CtlJumpTbl DC.W VidReset-CtlJumpTbl ;$00 => VidReset
- DC.W CtlGood-CtlJumpTbl ;$01 => CtlGood
- DC.W SetVidMode-CtlJumpTbl ;$02 => SetVidMode
-
- CtlBad MOVEQ #controlErr,D0 ; else say we don't do this one
- BRA.S CtlDone ; and return
-
- CtlGood MOVEQ #noErr,D0 ; return no error
-
- CtlDone MOVEM.L (SP)+,A0/A4/D4 ; restore registers.
- BRA ExitDrvr
-
- ;
- VidReset
- ;---------------------------------------------------------------------
- ;
- ; Reset the card to its default (one bit per pixel)
- ;
- ;---------------------------------------------------------------------
-
- BSR TFBInit ; initialize the card
- MOVE #OneBitMode,csMode(A2) ; return default mode
- MOVE #1,D1 ; get depth in D1
- MOVEQ #0,D0 ; get page in D0
- MOVE D0,csPage(A2) ; return the page
- MOVE.L dCtlStorage(A1),A3 ; get handle to our data
- MOVE.L (A3),A3 ; A3 = our data
- BSR TFBSetDepth ; set the depth from D1
- BSR TFBSetPage ; set the page from D0
- MOVE.L saveBaseAddr(A3),csBaseAddr(A2) ; return the base address
- BSR GrayScreen ; paint the screen gray
- BRA.S CtlGood ; => no error
-
- SetVidMode
- ;---------------------------------------------------------------------
- ;
- ; Set the card to the specified mode and page.
- ; If either is invalid, returns badMode error.
- ;
- ; If the card is already set to the specified mode, then do nothing.
- ;
- ; Note: Mode set is [1,2,4,8].
- ;
- ;---------------------------------------------------------------------
-
- MOVE.W csMode(A2),D1 ; D1 = mode
- BSR ChkMode ; get mode, check, map to depth (1, 2, 4 or 8) {D1 <- depth}
- BNE.S CtlBad ; => not a valid mode
-
- MOVE.W csPage(A2),D0 ; D0 = page
- BSR ChkPage ; check page
- BNE.S CtlBad ; => not a valid page
-
- ; Only set the mode if it has changed
- ; TFBSetDepth and TFBSetPage update the saved data in the dCtlStorage
-
- SetEm MOVE.L dCtlStorage(A1),A3 ; get handle to our data
- MOVE.L (A3),A3 ; A3 = our data
- MOVE.W csMode(A2),D2 ; D2 = mode
- CMP saveMode(A3),D2 ; has the mode changed?
- BEQ.S ModeOK1 ; => no, check the page
- BSR TFBSetDepth ; set the depth, get rowbytes
- BSR TFBSetPage ; set the page
- BRA.S NoChange ; => and return
-
- ModeOK1 BSR TFBSetPage ; set the page
-
- NoChange MOVE.L saveBaseAddr(A3),csBaseAddr(A2) ; return the base address
- BRA.S CtlGood ; => return no error
-
- ;
- **********************************************************************
- *
- * Video Driver Status Call Handler. Right now there are three calls:
- *
- * (0) Error
- * (1) Error
- * (2) GetMode
- * (3) Error
- * (4) GetPage
- * (5) GetPageBase
- *
- * Entry: A0 = param block
- * A1 = DCE pointer
- * Uses: A2 = cs parameters (ie. A2 <- csParam(A0)) (must be preserved)
- * A3 = scratch (doesn't need to be preserved)
- * D0-D3 = scratch (don't need to be preserved)
- *
- * Exit: D0 = error code
- *
- **********************************************************************
-
- VideoStatus MOVE.W csCode(A0),D0 ; get the opCode
- MOVE.L csParam(A0),A2 ; A2 <- Ptr to control parameters
-
-
- CMP.W #5,D0 ;IF csCode NOT IN [0..6] THEN
- BHI.S StatBad ; Error, csCode out of bounds.
- LSL.W #1,D0 ;Adjust csCode to be an index into the table.
- MOVE.W StatJumpTbl(PC,D0.W),D0 ;Get the relative offset to the routine.
- JMP StatJumpTbl(PC,D0.W) ;GOTO the proper routine.
-
- StatJumpTbl DC.W StatBad-StatJumpTbl ;$00 => Error
- DC.W StatBad-StatJumpTbl ;$01 => Error
- DC.W GetMode-StatJumpTbl ;$02 => GetMode
- DC.W StatBad-StatJumpTbl ;$03 => Error
- DC.W GetPage-StatJumpTbl ;$04 => GetPage
- DC.W GetPageBase-StatJumpTbl ;$05 => GetPageBase
-
- StatBad MOVEQ #statusErr,D0 ; else say we don't do this one
- BRA ExitDrvr ; and return
-
- StatGood MOVEQ #noErr,D0 ; return no error
- BRA ExitDrvr
-
-
- GetMode
- ;---------------------------------------------------------------------
- ;
- ; Return the current mode
- ;
- ;---------------------------------------------------------------------
-
- MOVE.L dCtlStorage(A1),A3 ; get handle to our storage
- MOVE.L (A3),A3 ; get pointer to our storage
- MOVE.W saveMode(A3),csMode(A2) ; return the mode
- MOVE.W savePage(A3),csPage(A2) ; return the page number
- MOVE.L saveBaseAddr(A3),csBaseAddr(A2) ; and the base address
-
- BRA.S StatGood ; => return no error
-
-
-
- GetPage
- ;---------------------------------------------------------------------
- ;
- ; Return the number of pages in the specified mode
- ;
- ;---------------------------------------------------------------------
-
- MOVE csMode(A2),D1 ; get the mode
- BSR ChkMode ; check mode, get depth in D1
- BNE StatBad ; => not a valid mode
-
- MOVE.L dCtlStorage(A1),A0 ; get private storage pointer
- TST.B VRAM256K(A0) ; 512K or 256K?
- BNE.S @1 ; if TRUE, then 256K of RAM
- MOVEQ #4,D0 ; if FALSE, 512K vRAM (and 1 more page per mode)
- BRA.S @2
- @1 MOVEQ #3,D0 ; get one-bit page count
- @2 DIVU D1,D0 ; divide by depth
- ADD #1,D0 ; make it one based
- MOVE D0,csPage(A2) ; return page count
- BRA StatGood ; => return no error
-
-
-
- ;
- GetPageBase
- ;---------------------------------------------------------------------
- ;
- ; Return the base address for the specified page in the current mode
- ;
- ;---------------------------------------------------------------------
-
- MOVE.L dCtlStorage(A1),A3 ; get handle to our storage
- MOVE.L (A3),A3 ; get pointer to our storage
- MOVE saveMode(A3),D1 ; get the current mode
- BSR ChkMode ; convert to depth in D1
- MOVE.W csPage(A2),D0 ; get the requested page
- BSR ChkPage ; is the page valid?
- BNE StatBad ; => no, just return
-
- MOVE saveMode(A3),D1 ; get the current mode
- SUB #OneBitMode,D1 ; make it 0 based
- LEA ModeTbl,A0 ; point to tables
- MULU 4(A0,D1*8),D0 ; calc page * rowBytes
- MULU 6(A0,D1*8),D0 ; calc page * rowBytes * height
- MOVEQ #4,D1 ; add offset for TFB
- ADD.L D1,D0 ; which doesn't use first long
- ADD.L dCtlDevBase(A1),D0 ; add base address for card
- MOVE.L D0,csBaseAddr(A2) ; return the base address
-
- BRA StatGood ; => return no error
-
-
- ;---------------------------------------------------------------------
- ;
- ; Exit from control or Status.
- ;
- ;---------------------------------------------------------------------
-
- ExitDrvr BTST #NoQueueBit,ioTrap(A0) ; no queue bit set?
- BEQ.S GoIODone ; => no, not immediate
- RTS ; otherwise, it was an immediate call
-
- GoIODone MOVE.L JIODone,A0 ; get the IODone address
- JMP (A0) ; invoke it
-
-
-
-
- **********************************************************************
- *
- * Utilities (Hardware dependent)
- *
- **********************************************************************
-
- TFBInit RTS ;Initialize the TFB
-
- TFBSetDepth RTS ;Set the depth.
-
- TFBSetPage RTS ;Set the page.
-
- ChkMode RTS ;Check the current mode.
-
- ChkPage RTS ;Check the current page.
-
- GrayScreen RTS ;Gray the screen.
-
- ModeTbl DC.W $AAAA,$AAAA,$0080,$01E0 ; one bit per pixel
- DC.W $CCCC,$CCCC,$0100,$01E0 ; two bit per pixel
- DC.W $F0F0,$F0F0,$0200,$01E0 ; four bit per pixel
- DC.W $FF00,$FF00,$0400,$01E0 ; eight bit per pixel
-
-